package com.edu.koudingmusic.tools;

import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.edu.koudingmusic.entities.SearchResult;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.parsers.ParserConfigurationException;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by Ming on 2016/2/28.
 * email 1715944993@qq.com
 */
public class DownloadUtils {

    private static final String TAG = "DownloadUtils";
    public static final String DOWNLOAD_URL = "/download?__o=%2Fsearch%2Fsong";

    //下载歌词成功
    public static final int SUCCESS_LRC = 1;
    //下载歌词失败
    public static final int FAILED_LRC = 2;

    //下载mp3音乐成功
    public static final int SUCCESS_MP3 = 3;
    //下载mp3音乐失败
    public static final int FAILED_MP3 = 4;

    // 获取mp3 url 成功
    public static final int GET_MP3_URL = 5;
    // 获取mp3 url 失败
    public static final int GET_FAILED_MP3_URL = 6;
    // 音乐已存在
    public static final int MUSIC_EXISTS = 7;

    private static DownloadUtils sInstance;

    private OnDownloadListener mListener;

    private ExecutorService mThreadPool;

    // 获取下载工具的实例
    public synchronized static DownloadUtils getInstance() {
        if (sInstance == null) {
            try {
                sInstance = new DownloadUtils();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            }
        }
        return sInstance;
    }

    public DownloadUtils() throws ParserConfigurationException {
        mThreadPool = Executors.newSingleThreadExecutor();
    }

    /**
     * 设置回调的监听器对象
     *
     * @param listener
     * @return
     */
    public DownloadUtils setListener(OnDownloadListener listener) {
        mListener = listener;
        return this;
    }

    /**
     * 下载的具体业务
     *
     * @param searchResult
     */
    public void download(final SearchResult searchResult) {

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case SUCCESS_LRC:
                        if (mListener != null) {
                            mListener.onDownload("歌词下载成功");
                        }
                        break;
                    case FAILED_LRC:
                        if (mListener != null) {
                            mListener.onFailed("歌词下载失败");
                        }
                        break;
                    case GET_MP3_URL:
                        Log.e(TAG, "handleMessage: " + msg.obj);
                        downloadMusic(searchResult, (String) msg.obj, this);
                        break;
                    case GET_FAILED_MP3_URL:
                        if (mListener != null) {
                            mListener.onFailed("下载失败，该歌曲为收藏或VIP类型或不存在");
                        }
                        break;
                    case SUCCESS_MP3:
                        if (mListener != null) {
                            mListener.onDownload(searchResult.getMusicName() + "已下载");
                            String url = Constant.BAIDU_URL + searchResult.getUrl();
                            Log.e(TAG, "handleMessage: lrc" + url);
                            downloadLrc(url, searchResult.getMusicName(), this);
                        }
                        break;
                    case FAILED_MP3:
                        if (mListener != null) {
                            mListener.onFailed(searchResult.getMusicName() + "下载失败");
                        }
                        break;

                    case MUSIC_EXISTS:
                        if (mListener != null) {
                            mListener.onFailed("音乐已存在");
                        }
                        break;
                }
            }
        };
        getDownloadMusicURL(searchResult, handler);

    }


    // 下载mp3音乐的具体方法
    public void downloadMusic(final SearchResult searchResult, final String url, final Handler handler) {

        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                File musicDirFile = new File(Environment.getExternalStorageDirectory() + Constant.DIR_MUSIC);
                if (!musicDirFile.exists()) {
                    musicDirFile.mkdirs();
                }
                // http://music.baidu.com/data/music/file/?link=&song_id=239896
                String mp3Url = Constant.BAIDU_URL + url;
                String target = musicDirFile + "/" + searchResult.getMusicName() + ".mp3";
                Log.e(TAG, "run: mp3url" + mp3Url + "====" + target);
                File fileTarget = new File(target);
                if (fileTarget.exists()) {
                    handler.obtainMessage(MUSIC_EXISTS).sendToTarget();
                    return;
                } else {
                    // 使用OkHttpClient
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(mp3Url).build();
                    try {
                        Response response = client.newCall(request).execute();
                        if (response.isSuccessful()) {
                            PrintStream ps = new PrintStream(fileTarget);
                            byte[] bytes = response.body().bytes();
                            ps.write(bytes, 0, bytes.length);
                            ps.close();
                            handler.obtainMessage(SUCCESS_MP3).sendToTarget();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        handler.obtainMessage(FAILED_MP3).sendToTarget();
                    }
                }
            }
        });

    }


    public void getDownloadMusicURL(final SearchResult searchResult, final Handler handler) {
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    String url = Constant.BAIDU_URL + "/song/" + searchResult.getUrl().substring(searchResult.getUrl().lastIndexOf("/") + 1) + DOWNLOAD_URL;
                    Log.e(TAG, "run: 下载歌曲的url" + url);
                    Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();
                    Elements targetElements = doc.select("a[data-btndata]");
                    if (targetElements.size() <= 0) {
                        handler.obtainMessage(GET_FAILED_MP3_URL).sendToTarget();
                        return;
                    }
                    for (Element e : targetElements) {
                        if (e.attr("href").contains(".mp3")) {
                            String result = e.attr("href");
                            Message message = handler.obtainMessage(GET_MP3_URL, result);
                            message.sendToTarget();
                            return;
                        }

                        if (e.attr("href").startsWith("/vip")) {
                            targetElements.remove(e);
                        }
                    }

                    if (targetElements.size() <= 0) {
                        handler.obtainMessage(GET_FAILED_MP3_URL).sendToTarget();
                        return;
                    }

                    String result = targetElements.get(0).attr("href");
                    Message message = handler.obtainMessage(GET_MP3_URL, result);
                    message.sendToTarget();
                } catch (IOException e) {
                    e.printStackTrace();
                    handler.obtainMessage(GET_FAILED_MP3_URL).sendToTarget();
                }
            }
        });
    }

    //下载歌词
    public void downloadLrc(final String url, final String musicName, final Handler handler) {
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();
                    Elements lrcTag = doc.select("div.lyric-content");
                    String lrcURL = lrcTag.attr("data-lrclink");
                    Log.e(TAG, "run: lrcURL" + lrcURL);
                    File lrcDirFile = new File(Environment.getExternalStorageDirectory() + Constant.DIR_LRC);
                    if (!lrcDirFile.exists()) {
                        lrcDirFile.mkdirs();
                    }
                    lrcURL = Constant.BAIDU_URL + lrcURL;
                    String target = lrcDirFile + "/" + musicName + ".lrc";
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(lrcURL).build();
                    try {
                        Response response = client.newCall(request).execute();
                        if (response.isSuccessful()) {
                            PrintStream ps = new PrintStream(new File(target));
                            byte[] bytes = response.body().bytes();
                            ps.write(bytes, 0, bytes.length);
                            ps.close();
                            handler.obtainMessage(SUCCESS_LRC, target).sendToTarget();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


    }

    // 自定义下载事件监听器
    public interface OnDownloadListener {
        public void onDownload(String mp3Url);
        public void onFailed(String error);
    }
}
